package cn.tedu.lucky.draw.server.job.config;

import cn.tedu.lucky.draw.server.job.listener.ActivityJobListener;
import cn.tedu.lucky.draw.server.job.processor.ActivityItemProcessor;
import cn.tedu.lucky.draw.server.protocol.po.Activity;
import cn.tedu.lucky.draw.server.repository.ActivityRepository;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.data.RepositoryItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.PathResource;

import java.io.File;

/**
 * 定义作业：将csv文件数据读取到数据库
 */
@Configuration
public class CsvToDBJobConfig {

    /**
     * job 构建工厂
     */
    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Autowired
    private ActivityRepository activityRepository;

    @Bean
    public ActivityItemProcessor activityItemProcessor(){
        return new ActivityItemProcessor();
    }

    @Bean
    public ActivityJobListener activityJobListener(){
        return new ActivityJobListener();
    }

    @Bean
    //定义 Item Reader
    public FlatFileItemReader<Activity> itemReader() {
        return new FlatFileItemReaderBuilder<Activity>()
                .name("activityItemReader") //配置实例名称
                .saveState(false) //不保存状态,如果作业失败重启了，不需要从上次失败的地方继续执行
                //读取文件，需要我们提供文件的读取路径，为其创建一个File对象,并提供路径
                .resource(new PathResource(new File("doc/activity.csv").getAbsolutePath()))
                .delimited() //指定当前文件用分隔符号，逗号
                .names("name", "description", "img", "status", "sort")//定义csv文件中每列数据对应的字段名称
                .targetType(Activity.class)//会将每一行数据都转换为一个活动对象
                .linesToSkip(1)//跳过第一行开始读取
                .build();
    }

    @Bean
    public ItemWriter<Activity> activityItemWriter(ActivityRepository repository){
        /**
         * 创建一个RepositoryItemWriter 实例
         * 帮助我们与Spring Data Jpa 配合使用，完成数据的写入
         */
        RepositoryItemWriter<Activity> writer = new RepositoryItemWriter<>();
        writer.setRepository(repository);
        writer.setMethodName("save");
        return writer;

    }

    @Bean
    public Step csvToDBStep() {
        return stepBuilderFactory.get("csvToDB-Step")
                /**
                 * 当前每次处理10000条数据
                 */
                .<Activity, Activity>chunk(10000)
                .reader(itemReader())
                .processor(activityItemProcessor())
                .writer(activityItemWriter(activityRepository))
                .build();
    }

    @Bean
    public Job csvToDBJob() {
        /**
         * 使用JobBuilderFactory创建一个新得job实例，命名为csvToDB-Step-Job
         */
        return jobBuilderFactory.get("csvToDB-Step-Job")
                /**
                 * 调用start 配置作业步骤
                 */
                .start(csvToDBStep())
                .incrementer(new RunIdIncrementer())
                .listener(activityJobListener())
                .build();
    }
}
